package com.meida.module.arc.provider.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.mybatis.vo.JoinBean;
import com.meida.common.security.OpenHelper;
import com.meida.common.security.OpenUser;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.RedisUtils;
import com.meida.common.utils.StringUtils;
import com.meida.module.admin.provider.service.BaseRoleService;
import com.meida.module.arc.client.constants.ArchiveConstants;
import com.meida.module.arc.client.entity.ArcCategory;
import com.meida.module.arc.client.entity.ArcCategorySuffix;
import com.meida.module.arc.client.entity.ArcCompilationRef;
import com.meida.module.arc.client.entity.ArcInfo;
import com.meida.module.arc.client.enums.ArchiveEnumInteger;
import com.meida.module.arc.client.enums.CategoryTypeEnum;
import com.meida.module.arc.client.utils.ArcUtils;
import com.meida.module.arc.provider.mapper.ArcCategoryMapper;
import com.meida.module.arc.provider.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * 门类接口实现类
 *
 * @author flyme
 * @date 2021-11-22
 */
@Service
@Transactional(rollbackFor = Exception.class)
@DS("sharding")
public class ArcCategoryServiceImpl extends BaseServiceImpl<ArcCategoryMapper, ArcCategory> implements ArcCategoryService {

    @Autowired
    private ArcCategorySuffixService arcCategorySuffixService;

    @Autowired
    private ArcFieldService arcFieldService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private ArcAuthTokenService arcAuthTokenService;

    @Autowired
    private ArcInfoService arcInfoService;
    @Autowired
    private ArcOriginalService arcOriginalService;


    @Autowired
    private BaseRoleService baseRoleService;

    @Autowired
    private ArcCategoryUserService arcCategoryUserService;

    @Value("${spring.datasource.dynamic.datasource.master.url:mysql}")
    private String dataSourceUrl;
    @Value("${spring.datasource.dynamic.datasource.master.password:zboao990}")
    private String password;
    @Value("${meida.uploadFolder:'/upload/'}")
    private String uploadFolder;


    @Autowired
    private SyncServiceImpl syncService;

    @Autowired
    ArcInfoCollectService arcInfoCollectService;

    @Autowired
    ArcDestoryService arcDestoryService;

    private String genSysCode(Long parentId) {
        String parentSysCode = null;
        //1查询父节点sysCode
        if (!ArchiveConstants.ROOT_PARENT_ID.equals(parentId) && FlymeUtils.isNotEmpty(parentId)) {
            ArcCategory dict = getById(parentId);
            parentSysCode = dict.getSysCode();
        }
        //2查询子节点最大sysCode
        CriteriaQuery<ArcCategory> query = new CriteriaQuery<ArcCategory>(ArcCategory.class);
        query.lambda().eq(ArcCategory::getParentId, parentId);
        query.orderByDesc("sysCode");
        query.limit(1);
        ArcCategory preSysCodeObj = getOne(query);
        if (preSysCodeObj == null) {
            return ArcUtils.genNextSysCode(parentSysCode, null);
        } else {
            return ArcUtils.genNextSysCode(parentSysCode, preSysCodeObj.getSysCode());
        }
    }

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, ArcCategory category, EntityMap extra) {
        category.setCategoryId(IdWorker.getId());
        ApiAssert.isNotEmpty("参数不能为空", category);
        ApiAssert.isNotEmpty("门类名称不能为空", category.getCnName());
        ApiAssert.isNotEmpty("全宗id不能为空", category.getQzId());
        ApiAssert.isNotEmpty("父id不能为空", category.getParentId());
        ApiAssert.isNotEmpty("门类类型不能为空", category.getType());
        arcAuthTokenService.checkCategoryCount();
        if (!CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(category.getType())
                && !CategoryTypeEnum.CATEGORY_TYPE_5.getCode().equals(category.getType())) {
            ApiAssert.isNotEmpty("数据库表名不能为空", category.getTableName());
        }

        if (category.getParentId().longValue() == 4) {
            long count = this.count(new QueryWrapper<ArcCategory>().lambda().eq(ArcCategory::getParentId, category.getParentId()));
            if (count > 3) {
                ApiAssert.failure("档案保管最多创建3个门类");
            }
        }
        Long copyCategoryId = cs.getRequestMap().getLong("copyCategoryId");
        Integer copyCount = cs.getRequestMap().getInt("copyCount");
        if (CategoryTypeEnum.CATEGORY_TYPE_5.getCode().equals(category.getType())) {
            //模板复刻
            ApiAssert.isNotEmpty("模板门类id为空", copyCategoryId);
            ApiAssert.isNotEmpty("模板复制数量为空", copyCount);
            if (copyCount < 1) {
                ApiAssert.failure("复刻份数最小为1");
            }
            if (copyCount > 10) {
                ApiAssert.failure("复刻份数最大为10");
            }
            ArcCategory copyCategory = this.getById(copyCategoryId);
            ApiAssert.isNotEmpty("模板门类为空", copyCategory);
            category.setType(copyCategory.getType());
            if (!CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(category.getType())) {
                Map tableNameMap = (Map) getTableName(null).getData();
                category.setTableName(tableNameMap.get("tableName").toString());
            }
        }


        OpenUser user = OpenHelper.getUser();
        if (ArchiveConstants.ROOT_PARENT_ID.equals(category.getParentId())) {
            if (!ArchiveEnumInteger.IS_ADMIN.getCode().equals(user.getSuperAdmin())) {
                return ResultBody.failed("只有系统管理员才能添加根节点");
            }
            if (category.getType().equals(CategoryTypeEnum.CATEGORY_TYPE_0.getCode())) {
                category.setIsSystem(ArchiveEnumInteger.IS_SYSTEM.getCode());
            } else {
                category.setIsSystem(ArchiveEnumInteger.IS_NOT_SYSTEM.getCode());
            }
        } else {
            category.setIsSystem(ArchiveEnumInteger.IS_NOT_SYSTEM.getCode());
        }

        //生成序号
        CriteriaQuery<ArcCategory> query = new CriteriaQuery<ArcCategory>(ArcCategory.class);
        query.eq("parentId", category.getParentId());
        query.orderByDesc("seq");
        query.limit(1);
        ArcCategory obj = this.baseMapper.selectOne(query);
        if (FlymeUtils.isEmpty(obj)) {
            category.setSeq(0);
        } else {
            category.setSeq(obj.getSeq() + 1);
        }

        //生成系统编码
        category.setSysCode(genSysCode(category.getParentId()));

        return ResultBody.ok();
    }

    private void doCreateCategory(ArcCategory category) {
        if (!CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(category.getType())) {

            //校验表名后缀状态
            CriteriaQuery<ArcCategorySuffix> suffixQuery = new CriteriaQuery<ArcCategorySuffix>(ArcCategorySuffix.class);
            suffixQuery.lambda().eq(ArcCategorySuffix::getSuffix, category.getTableName());
            Long count = arcCategorySuffixService.getBaseMapper().selectCount(suffixQuery);
            if (count > 0) {
                ApiAssert.failure("数据库表名已存在，请重新创建");
            }
            //占用后缀
            addArcCategorySuffix(category.getTableName(), category.getCategoryId());
            delRedisTableName(category.getTableName());
            //创建门类信息
            genCategoryTable(category.getTableName());
        }
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, ArcCategory t, EntityMap extra) {

        //1动态创建档案信息表   档案原文表
        //已修改到controller的save方法执行 genCategoryTable(t.getTableName());
        //2添加门类对应字段的配置信息（处理门类复制问题）

        doCreateCategory(t);
        Long copyCategoryId = cs.getRequestMap().getLong("copyCategoryId");
        Integer copyCount = cs.getRequestMap().getInt("copyCount");
        Map<String, String> map = new HashMap();

        //门类复制
        if (CategoryTypeEnum.CATEGORY_TYPE_5.getCode().equals(cs.getRequestMap().getInt("type"))) {
            ArcCategory copyCategory = this.getById(copyCategoryId);
            this.arcFieldService.copyArcCategoryField(t, copyCategory);
            //模板复刻
            Map<Long, Long> idRef = new HashMap<>();
            idRef.put(copyCategory.getCategoryId(), t.getCategoryId());
            idRef.put(copyCategory.getParentId(), t.getParentId());
            List<String> list = doCategoryCopy(t, copyCategory, copyCount, idRef);
            list.add(t.getCategoryId().toString());
            map.put("categoryIds", StringUtils.join(list, ","));
        } else {
            this.arcFieldService.batchAddArcField(t.getCategoryId());
            map.put("categoryIds", t.getCategoryId().toString());
        }

        map.put("qzId", t.getQzId().toString());
        map.put("roleIds",
                baseRoleService.getUserRoles(OpenHelper.getUserId()).stream().map(item -> {
                    return item.getRoleId().toString();
                }).collect(Collectors.joining(",")));
        arcCategoryUserService.saveOrUpdate(map);
        return ResultBody.ok("保存成功", t);
    }


    private List<String> doCategoryCopy(ArcCategory srcCategory, ArcCategory copyCategory, int max, Map<Long, Long> idRef) {
        //递归复制下级
        //1,根据copyCategory递归查询所有的子级
        List<ArcCategory> copyCategoryList = this.list(Wrappers.lambdaQuery(ArcCategory.class)
                .likeRight(ArcCategory::getSysCode, copyCategory.getSysCode())
                .orderByAsc(ArcCategory::getSysCode));
        List<String> categoryIds = new ArrayList<>();
        //复刻份数
        for (int i = 1; i <= max; i++) {
            //递归子级
            inner:
            for (int j = 0; j < copyCategoryList.size(); j++) {

                ArcCategory obj = copyCategoryList.get(j);
                if (i == 1 && j == 0) {
                    //第一个已经创建
                    continue inner;
                }
                ArcCategory arcCategory = new ArcCategory();
                BeanUtil.copyProperties(obj, arcCategory);
                if (j == 0) {
                    arcCategory.setCnName(srcCategory.getCnName() + i);
                }
                arcCategory.setParentId(idRef.get(arcCategory.getParentId()));
                Long id = IdWorker.getId();
                idRef.put(arcCategory.getCategoryId(), id);
                arcCategory.setCategoryId(id);
                if (!CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(arcCategory.getType())) {
                    Map tableNameMap = (HashMap) getTableName(null).getData();
                    arcCategory.setTableName(tableNameMap.get("tableName").toString());
                }
                this.doCreateCategory(arcCategory);

                //生成序号
                CriteriaQuery<ArcCategory> query = new CriteriaQuery<ArcCategory>(ArcCategory.class);
                query.eq("parentId", arcCategory.getParentId());
                query.orderByDesc("seq");
                query.limit(1);
                ArcCategory tempObj = this.baseMapper.selectOne(query);
                if (FlymeUtils.isEmpty(tempObj)) {
                    arcCategory.setSeq(0);
                } else {
                    arcCategory.setSeq(tempObj.getSeq() + 1);
                }

                //生成系统编码
                arcCategory.setSysCode(genSysCode(arcCategory.getParentId()));
                this.save(arcCategory);
                this.arcFieldService.copyArcCategoryField(arcCategory, obj);
                categoryIds.add(arcCategory.getCategoryId().toString());
            }

        }
        return categoryIds;
    }


    //新增门类，基于系统字段/业务字段生成档案信息表   基于原文字段生成原文表
    //DDL 隐式提交，不能控制事务 所以将数据表创建放在门类添加之前，如果门类添加失败则不执行ddl，
    //
    @Override
    public synchronized void genCategoryTable(String tableNameSuffix) {
        try {
            if (FlymeUtils.isNotEmpty(dataSourceUrl) && dataSourceUrl.indexOf("postgresql") > -1 && dataSourceUrl.indexOf("strToNull") == -1) {
                String filePath = uploadFolder + "archive" + IdWorker.getIdStr() + ".sql";
                String tmp = dataSourceUrl.substring(dataSourceUrl.indexOf("//") + 2);
                String[] split = tmp.substring(0, tmp.indexOf("/")).split(":");

                String host = split[0], port = split[1];
                if (ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR > 0) {
                    for (int i = 0; i < ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR; i++) {
                        String info = "CREATE TABLE tableName ( \"arcInfoId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" NVARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" NVARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"expand\" text, \"parentId\" int8, \"outSideId\" int8, \"deleteTime\" NVARCHAR(25), \"createBatch\" NVARCHAR(50), \"adjustTime\" NVARCHAR(25), \"viewFileCount\" int4, \"viewCount\" int4, \"qzId\" int8, \"storeRoomId\" int8, \"indexStatus\" int4, \"originalCount\" int4, \"commentCount\" int4, \"categoryId\" int8, \"isUse\" int4, \"isStore\" int4, \"isRecycle\" int4, \"isDestory\" int4, \"isCompilation\" int4, \"status\" int4, \"unitId\" int8, \"seq\" NVARCHAR(10), \"storageLocationName\" NVARCHAR(255), \"compilationName\" NVARCHAR(255), \"childCount\" int4, \"refCount\" int4, \"handouverUnit\" NVARCHAR(255), \"fondsNo\" NVARCHAR(100), \"numberNo\" int4, \"arcFlag\" NVARCHAR(60), \"arcNo\" NVARCHAR(255), \"filingYear\" NVARCHAR(10), \"pageNo\" int4, \"retention\" NVARCHAR(10), \"createdDate\" NVARCHAR(25), \"handoverTime\" NVARCHAR(25), \"arcCtgNo\" NVARCHAR(50), \"pieceNo\" NVARCHAR(20), \"maintitle\" NVARCHAR(255), \"securityClass\" NVARCHAR(20), \"folderLocation\" NVARCHAR(50), \"pigeonholeDate\" NVARCHAR(25), \"department\" NVARCHAR(255), \"contentNo\" NVARCHAR(20), \"relevanceNo\" NVARCHAR(20), \"responsibleby\" NVARCHAR(100), \"isRemind\" int4 ); COMMENT ON COLUMN tableName.\"arcInfoId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"expand\" IS '扩展字段'; COMMENT ON COLUMN tableName.\"parentId\" IS '父id'; COMMENT ON COLUMN tableName.\"outSideId\" IS '外部来源id'; COMMENT ON COLUMN tableName.\"deleteTime\" IS '删除时间'; COMMENT ON COLUMN tableName.\"createBatch\" IS '创建批次'; COMMENT ON COLUMN tableName.\"adjustTime\" IS '调出时间'; COMMENT ON COLUMN tableName.\"viewFileCount\" IS '查看原文次数'; COMMENT ON COLUMN tableName.\"viewCount\" IS '查看条目次数'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"storeRoomId\" IS '库房id'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"originalCount\" IS '原文数量'; COMMENT ON COLUMN tableName.\"commentCount\" IS '评论数量'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"isUse\" IS '是否利用'; COMMENT ON COLUMN tableName.\"isStore\" IS '是否入库'; COMMENT ON COLUMN tableName.\"isRecycle\" IS '是否回收站'; COMMENT ON COLUMN tableName.\"isDestory\" IS '是否销毁'; COMMENT ON COLUMN tableName.\"isCompilation\" IS '是否编研'; COMMENT ON COLUMN tableName.\"status\" IS '状态'; COMMENT ON COLUMN tableName.\"unitId\" IS '单位id'; COMMENT ON COLUMN tableName.\"seq\" IS '顺序号'; COMMENT ON COLUMN tableName.\"storageLocationName\" IS '存放位置'; COMMENT ON COLUMN tableName.\"compilationName\" IS '编研素材类型名称'; COMMENT ON COLUMN tableName.\"childCount\" IS '子条目数'; COMMENT ON COLUMN tableName.\"refCount\" IS '关联数量'; COMMENT ON COLUMN tableName.\"handouverUnit\" IS '原移交单位'; COMMENT ON COLUMN tableName.\"fondsNo\" IS '二级全宗号'; COMMENT ON COLUMN tableName.\"numberNo\" IS '份数'; COMMENT ON COLUMN tableName.\"arcFlag\" IS '归档标识'; COMMENT ON COLUMN tableName.\"arcNo\" IS '档号'; COMMENT ON COLUMN tableName.\"filingYear\" IS '归档年度'; COMMENT ON COLUMN tableName.\"pageNo\" IS '页数'; COMMENT ON COLUMN tableName.\"retention\" IS '保管期限（保管期限Y永久，D30定期30年，D10定期10年）'; COMMENT ON COLUMN tableName.\"createdDate\" IS '文件形成时间'; COMMENT ON COLUMN tableName.\"handoverTime\" IS '移交时间'; COMMENT ON COLUMN tableName.\"arcCtgNo\" IS '分类号'; COMMENT ON COLUMN tableName.\"pieceNo\" IS '件号'; COMMENT ON COLUMN tableName.\"maintitle\" IS '题名'; COMMENT ON COLUMN tableName.\"securityClass\" IS '密级'; COMMENT ON COLUMN tableName.\"folderLocation\" IS '存放位置'; COMMENT ON COLUMN tableName.\"pigeonholeDate\" IS '归档日期'; COMMENT ON COLUMN tableName.\"department\" IS '部门名称'; COMMENT ON COLUMN tableName.\"contentNo\" IS '目录号'; COMMENT ON COLUMN tableName.\"relevanceNo\" IS '批量关联号'; COMMENT ON COLUMN tableName.\"responsibleby\" IS '责任者'; COMMENT ON COLUMN tableName.\"isRemind\" IS '设置提醒 1是 0否'; COMMENT ON TABLE tableName IS '档案信息表';";
                        String origina = "CREATE TABLE tableName ( \"arcOriginalId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" NVARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" NVARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"arcInfoId\" int8, \"categoryId\" int8, \"qzId\" int8, \"fileName\" NVARCHAR(255), \"fileNote\" NVARCHAR(255), \"filePixel\" NVARCHAR(255), \"fileDpi\" NVARCHAR(255), \"fileSize\" NVARCHAR(32), \"fileType\" NVARCHAR(32), \"filePath\" NVARCHAR(255), \"md5\" NVARCHAR(100), \"indexStatus\" int4, \"seq\" int4, \"fileContenttype\" NVARCHAR(200), \"localPath\" NVARCHAR(255), \"ossPath\" NVARCHAR(255) ); COMMENT ON COLUMN tableName.\"arcOriginalId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"arcInfoId\" IS '档案业务id'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"fileName\" IS '原文名称'; COMMENT ON COLUMN tableName.\"fileNote\" IS '原文注释'; COMMENT ON COLUMN tableName.\"filePixel\" IS '像素'; COMMENT ON COLUMN tableName.\"fileDpi\" IS '分辨率'; COMMENT ON COLUMN tableName.\"fileSize\" IS '原文大小'; COMMENT ON COLUMN tableName.\"fileType\" IS '原文类型'; COMMENT ON COLUMN tableName.\"filePath\" IS '访问路径'; COMMENT ON COLUMN tableName.\"md5\" IS 'MD5'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"seq\" IS '原文序号'; COMMENT ON COLUMN tableName.\"fileContenttype\" IS '原文内容类型'; COMMENT ON COLUMN tableName.\"localPath\" IS '本地路径'; COMMENT ON COLUMN tableName.\"ossPath\" IS 'oss路径'; COMMENT ON TABLE tableName IS '档案原文表';";
                        StringBuilder sb = new StringBuilder();
                        sb.append(info.replace("tableName", ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix + "_" + i));
                        sb.append("\n");
                        sb.append(origina.replace("tableName", ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix + "_" + i));
                        FileUtil.writeUtf8String(sb.toString(), filePath);
                        //ArcUtils.execPGSql(host, port, password, filePath);
                        this.baseMapper.createArcInfoTablePg(ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix + "_" + i);
                        this.baseMapper.createArcOriginaTablePg(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix + "_" + i);
                    }
                } else {
                    String info = "CREATE TABLE tableName ( \"arcInfoId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" NVARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" NVARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"expand\" text, \"parentId\" int8, \"outSideId\" int8, \"deleteTime\" NVARCHAR(25), \"createBatch\" NVARCHAR(50), \"adjustTime\" NVARCHAR(25), \"viewFileCount\" int4, \"viewCount\" int4, \"qzId\" int8, \"storeRoomId\" int8, \"indexStatus\" int4, \"originalCount\" int4, \"commentCount\" int4, \"categoryId\" int8, \"isUse\" int4, \"isStore\" int4, \"isRecycle\" int4, \"isDestory\" int4, \"isCompilation\" int4, \"status\" int4, \"unitId\" int8, \"seq\" NVARCHAR(10), \"storageLocationName\" NVARCHAR(255), \"compilationName\" NVARCHAR(255), \"childCount\" int4, \"refCount\" int4, \"handouverUnit\" NVARCHAR(255), \"fondsNo\" NVARCHAR(100), \"numberNo\" int4, \"arcFlag\" NVARCHAR(60), \"arcNo\" NVARCHAR(255), \"filingYear\" NVARCHAR(10), \"pageNo\" int4, \"retention\" NVARCHAR(10), \"createdDate\" NVARCHAR(25), \"handoverTime\" NVARCHAR(25), \"arcCtgNo\" NVARCHAR(50), \"pieceNo\" NVARCHAR(20), \"maintitle\" NVARCHAR(255), \"securityClass\" NVARCHAR(20), \"folderLocation\" NVARCHAR(50), \"pigeonholeDate\" NVARCHAR(25), \"department\" NVARCHAR(255), \"contentNo\" NVARCHAR(20), \"relevanceNo\" NVARCHAR(20), \"responsibleby\" NVARCHAR(100), \"isRemind\" int4 ); COMMENT ON COLUMN tableName.\"arcInfoId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"expand\" IS '扩展字段'; COMMENT ON COLUMN tableName.\"parentId\" IS '父id'; COMMENT ON COLUMN tableName.\"outSideId\" IS '外部来源id'; COMMENT ON COLUMN tableName.\"deleteTime\" IS '删除时间'; COMMENT ON COLUMN tableName.\"createBatch\" IS '创建批次'; COMMENT ON COLUMN tableName.\"adjustTime\" IS '调出时间'; COMMENT ON COLUMN tableName.\"viewFileCount\" IS '查看原文次数'; COMMENT ON COLUMN tableName.\"viewCount\" IS '查看条目次数'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"storeRoomId\" IS '库房id'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"originalCount\" IS '原文数量'; COMMENT ON COLUMN tableName.\"commentCount\" IS '评论数量'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"isUse\" IS '是否利用'; COMMENT ON COLUMN tableName.\"isStore\" IS '是否入库'; COMMENT ON COLUMN tableName.\"isRecycle\" IS '是否回收站'; COMMENT ON COLUMN tableName.\"isDestory\" IS '是否销毁'; COMMENT ON COLUMN tableName.\"isCompilation\" IS '是否编研'; COMMENT ON COLUMN tableName.\"status\" IS '状态'; COMMENT ON COLUMN tableName.\"unitId\" IS '单位id'; COMMENT ON COLUMN tableName.\"seq\" IS '顺序号'; COMMENT ON COLUMN tableName.\"storageLocationName\" IS '存放位置'; COMMENT ON COLUMN tableName.\"compilationName\" IS '编研素材类型名称'; COMMENT ON COLUMN tableName.\"childCount\" IS '子条目数'; COMMENT ON COLUMN tableName.\"refCount\" IS '关联数量'; COMMENT ON COLUMN tableName.\"handouverUnit\" IS '原移交单位'; COMMENT ON COLUMN tableName.\"fondsNo\" IS '二级全宗号'; COMMENT ON COLUMN tableName.\"numberNo\" IS '份数'; COMMENT ON COLUMN tableName.\"arcFlag\" IS '归档标识'; COMMENT ON COLUMN tableName.\"arcNo\" IS '档号'; COMMENT ON COLUMN tableName.\"filingYear\" IS '归档年度'; COMMENT ON COLUMN tableName.\"pageNo\" IS '页数'; COMMENT ON COLUMN tableName.\"retention\" IS '保管期限（保管期限Y永久，D30定期30年，D10定期10年）'; COMMENT ON COLUMN tableName.\"createdDate\" IS '文件形成时间'; COMMENT ON COLUMN tableName.\"handoverTime\" IS '移交时间'; COMMENT ON COLUMN tableName.\"arcCtgNo\" IS '分类号'; COMMENT ON COLUMN tableName.\"pieceNo\" IS '件号'; COMMENT ON COLUMN tableName.\"maintitle\" IS '题名'; COMMENT ON COLUMN tableName.\"securityClass\" IS '密级'; COMMENT ON COLUMN tableName.\"folderLocation\" IS '存放位置'; COMMENT ON COLUMN tableName.\"pigeonholeDate\" IS '归档日期'; COMMENT ON COLUMN tableName.\"department\" IS '部门名称'; COMMENT ON COLUMN tableName.\"contentNo\" IS '目录号'; COMMENT ON COLUMN tableName.\"relevanceNo\" IS '批量关联号'; COMMENT ON COLUMN tableName.\"responsibleby\" IS '责任者'; COMMENT ON COLUMN tableName.\"isRemind\" IS '设置提醒 1是 0否'; COMMENT ON TABLE tableName IS '档案信息表';";
                    String origina = "CREATE TABLE tableName ( \"arcOriginalId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" NVARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" NVARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"arcInfoId\" int8, \"categoryId\" int8, \"qzId\" int8, \"fileName\" NVARCHAR(255), \"fileNote\" NVARCHAR(255), \"filePixel\" NVARCHAR(255), \"fileDpi\" NVARCHAR(255), \"fileSize\" NVARCHAR(32), \"fileType\" NVARCHAR(32), \"filePath\" NVARCHAR(255), \"md5\" NVARCHAR(100), \"indexStatus\" int4, \"seq\" int4, \"fileContenttype\" NVARCHAR(200), \"localPath\" NVARCHAR(255), \"ossPath\" NVARCHAR(255) ); COMMENT ON COLUMN tableName.\"arcOriginalId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"arcInfoId\" IS '档案业务id'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"fileName\" IS '原文名称'; COMMENT ON COLUMN tableName.\"fileNote\" IS '原文注释'; COMMENT ON COLUMN tableName.\"filePixel\" IS '像素'; COMMENT ON COLUMN tableName.\"fileDpi\" IS '分辨率'; COMMENT ON COLUMN tableName.\"fileSize\" IS '原文大小'; COMMENT ON COLUMN tableName.\"fileType\" IS '原文类型'; COMMENT ON COLUMN tableName.\"filePath\" IS '访问路径'; COMMENT ON COLUMN tableName.\"md5\" IS 'MD5'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"seq\" IS '原文序号'; COMMENT ON COLUMN tableName.\"fileContenttype\" IS '原文内容类型'; COMMENT ON COLUMN tableName.\"localPath\" IS '本地路径'; COMMENT ON COLUMN tableName.\"ossPath\" IS 'oss路径'; COMMENT ON TABLE tableName IS '档案原文表';";
                    StringBuilder sb = new StringBuilder();
                    sb.append(info.replace("tableName", ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix));
                    sb.append("\n");
                    sb.append(origina.replace("tableName", ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix));
                    FileUtil.writeUtf8String(sb.toString(), filePath);
                    ArcUtils.execPGSql(host, port, password, filePath);
                    this.baseMapper.createArcInfoTablePg(ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix);
                    this.baseMapper.createArcOriginaTablePg(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix);


                }
            } else if (FlymeUtils.isNotEmpty(dataSourceUrl) && dataSourceUrl.indexOf("strToNull") > -1) {
                String filePath = uploadFolder + "archive" + IdWorker.getIdStr() + ".sql";
                String tmp = dataSourceUrl.substring(dataSourceUrl.indexOf("//") + 2);
                String[] split = tmp.substring(0, tmp.indexOf("/")).split(":");

                String host = split[0], port = split[1];
                if (ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR > 0) {
                    for (int i = 0; i < ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR; i++) {
                        String info = "CREATE TABLE tableName ( \"arcInfoId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" VARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" VARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"expand\" text, \"parentId\" int8, \"outSideId\" int8, \"deleteTime\" VARCHAR(25), \"createBatch\" VARCHAR(50), \"adjustTime\" VARCHAR(25), \"viewFileCount\" int4, \"viewCount\" int4, \"qzId\" int8, \"storeRoomId\" int8, \"indexStatus\" int4, \"originalCount\" int4, \"commentCount\" int4, \"categoryId\" int8, \"isUse\" int4, \"isStore\" int4, \"isRecycle\" int4, \"isDestory\" int4, \"isCompilation\" int4, \"status\" int4, \"unitId\" int8, \"seq\" VARCHAR(10), \"storageLocationName\" VARCHAR(255), \"compilationName\" VARCHAR(255), \"childCount\" int4, \"refCount\" int4, \"handouverUnit\" VARCHAR(255), \"fondsNo\" VARCHAR(100), \"numberNo\" int4, \"arcFlag\" VARCHAR(60), \"arcNo\" VARCHAR(255), \"filingYear\" VARCHAR(10), \"pageNo\" int4, \"retention\" VARCHAR(10), \"createdDate\" VARCHAR(25), \"handoverTime\" VARCHAR(25), \"arcCtgNo\" VARCHAR(50), \"pieceNo\" VARCHAR(20), \"maintitle\" VARCHAR(255), \"securityClass\" VARCHAR(20), \"folderLocation\" VARCHAR(50), \"pigeonholeDate\" VARCHAR(25), \"department\" VARCHAR(255), \"contentNo\" VARCHAR(20), \"relevanceNo\" VARCHAR(20), \"responsibleby\" VARCHAR(100), \"isRemind\" int4 ); COMMENT ON COLUMN tableName.\"arcInfoId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"expand\" IS '扩展字段'; COMMENT ON COLUMN tableName.\"parentId\" IS '父id'; COMMENT ON COLUMN tableName.\"outSideId\" IS '外部来源id'; COMMENT ON COLUMN tableName.\"deleteTime\" IS '删除时间'; COMMENT ON COLUMN tableName.\"createBatch\" IS '创建批次'; COMMENT ON COLUMN tableName.\"adjustTime\" IS '调出时间'; COMMENT ON COLUMN tableName.\"viewFileCount\" IS '查看原文次数'; COMMENT ON COLUMN tableName.\"viewCount\" IS '查看条目次数'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"storeRoomId\" IS '库房id'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"originalCount\" IS '原文数量'; COMMENT ON COLUMN tableName.\"commentCount\" IS '评论数量'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"isUse\" IS '是否利用'; COMMENT ON COLUMN tableName.\"isStore\" IS '是否入库'; COMMENT ON COLUMN tableName.\"isRecycle\" IS '是否回收站'; COMMENT ON COLUMN tableName.\"isDestory\" IS '是否销毁'; COMMENT ON COLUMN tableName.\"isCompilation\" IS '是否编研'; COMMENT ON COLUMN tableName.\"status\" IS '状态'; COMMENT ON COLUMN tableName.\"unitId\" IS '单位id'; COMMENT ON COLUMN tableName.\"seq\" IS '顺序号'; COMMENT ON COLUMN tableName.\"storageLocationName\" IS '存放位置'; COMMENT ON COLUMN tableName.\"compilationName\" IS '编研素材类型名称'; COMMENT ON COLUMN tableName.\"childCount\" IS '子条目数'; COMMENT ON COLUMN tableName.\"refCount\" IS '关联数量'; COMMENT ON COLUMN tableName.\"handouverUnit\" IS '原移交单位'; COMMENT ON COLUMN tableName.\"fondsNo\" IS '二级全宗号'; COMMENT ON COLUMN tableName.\"numberNo\" IS '份数'; COMMENT ON COLUMN tableName.\"arcFlag\" IS '归档标识'; COMMENT ON COLUMN tableName.\"arcNo\" IS '档号'; COMMENT ON COLUMN tableName.\"filingYear\" IS '归档年度'; COMMENT ON COLUMN tableName.\"pageNo\" IS '页数'; COMMENT ON COLUMN tableName.\"retention\" IS '保管期限（保管期限Y永久，D30定期30年，D10定期10年）'; COMMENT ON COLUMN tableName.\"createdDate\" IS '文件形成时间'; COMMENT ON COLUMN tableName.\"handoverTime\" IS '移交时间'; COMMENT ON COLUMN tableName.\"arcCtgNo\" IS '分类号'; COMMENT ON COLUMN tableName.\"pieceNo\" IS '件号'; COMMENT ON COLUMN tableName.\"maintitle\" IS '题名'; COMMENT ON COLUMN tableName.\"securityClass\" IS '密级'; COMMENT ON COLUMN tableName.\"folderLocation\" IS '存放位置'; COMMENT ON COLUMN tableName.\"pigeonholeDate\" IS '归档日期'; COMMENT ON COLUMN tableName.\"department\" IS '部门名称'; COMMENT ON COLUMN tableName.\"contentNo\" IS '目录号'; COMMENT ON COLUMN tableName.\"relevanceNo\" IS '批量关联号'; COMMENT ON COLUMN tableName.\"responsibleby\" IS '责任者'; COMMENT ON COLUMN tableName.\"isRemind\" IS '设置提醒 1是 0否'; COMMENT ON TABLE tableName IS '档案信息表';";
                        String origina = "CREATE TABLE tableName ( \"arcOriginalId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" VARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" VARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"arcInfoId\" int8, \"categoryId\" int8, \"qzId\" int8, \"fileName\" VARCHAR(255), \"fileNote\" VARCHAR(255), \"filePixel\" VARCHAR(255), \"fileDpi\" VARCHAR(255), \"fileSize\" VARCHAR(32), \"fileType\" VARCHAR(32), \"filePath\" VARCHAR(255), \"md5\" VARCHAR(100), \"indexStatus\" int4, \"seq\" int4, \"fileContenttype\" VARCHAR(200), \"localPath\" VARCHAR(255), \"ossPath\" VARCHAR(255) ); COMMENT ON COLUMN tableName.\"arcOriginalId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"arcInfoId\" IS '档案业务id'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"fileName\" IS '原文名称'; COMMENT ON COLUMN tableName.\"fileNote\" IS '原文注释'; COMMENT ON COLUMN tableName.\"filePixel\" IS '像素'; COMMENT ON COLUMN tableName.\"fileDpi\" IS '分辨率'; COMMENT ON COLUMN tableName.\"fileSize\" IS '原文大小'; COMMENT ON COLUMN tableName.\"fileType\" IS '原文类型'; COMMENT ON COLUMN tableName.\"filePath\" IS '访问路径'; COMMENT ON COLUMN tableName.\"md5\" IS 'MD5'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"seq\" IS '原文序号'; COMMENT ON COLUMN tableName.\"fileContenttype\" IS '原文内容类型'; COMMENT ON COLUMN tableName.\"localPath\" IS '本地路径'; COMMENT ON COLUMN tableName.\"ossPath\" IS 'oss路径'; COMMENT ON TABLE tableName IS '档案原文表';";
                        StringBuilder sb = new StringBuilder();
                        sb.append(info.replace("tableName", ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix + "_" + i));
                        sb.append("\n");
                        sb.append(origina.replace("tableName", ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix + "_" + i));
                        FileUtil.writeUtf8String(sb.toString(), filePath);
                        //ArcUtils.execPGSql(host, port, password, filePath);
                        this.baseMapper.createArcInfoTableHg(ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix + "_" + i);
                        this.baseMapper.createArcOriginaTableHg(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix + "_" + i);
                    }
                } else {
                    String info = "CREATE TABLE tableName ( \"arcInfoId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" VARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" VARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"expand\" text, \"parentId\" int8, \"outSideId\" int8, \"deleteTime\" VARCHAR(25), \"createBatch\" VARCHAR(50), \"adjustTime\" VARCHAR(25), \"viewFileCount\" int4, \"viewCount\" int4, \"qzId\" int8, \"storeRoomId\" int8, \"indexStatus\" int4, \"originalCount\" int4, \"commentCount\" int4, \"categoryId\" int8, \"isUse\" int4, \"isStore\" int4, \"isRecycle\" int4, \"isDestory\" int4, \"isCompilation\" int4, \"status\" int4, \"unitId\" int8, \"seq\" VARCHAR(10), \"storageLocationName\" VARCHAR(255), \"compilationName\" VARCHAR(255), \"childCount\" int4, \"refCount\" int4, \"handouverUnit\" VARCHAR(255), \"fondsNo\" VARCHAR(100), \"numberNo\" int4, \"arcFlag\" VARCHAR(60), \"arcNo\" VARCHAR(255), \"filingYear\" VARCHAR(10), \"pageNo\" int4, \"retention\" VARCHAR(10), \"createdDate\" VARCHAR(25), \"handoverTime\" VARCHAR(25), \"arcCtgNo\" VARCHAR(50), \"pieceNo\" VARCHAR(20), \"maintitle\" VARCHAR(255), \"securityClass\" VARCHAR(20), \"folderLocation\" VARCHAR(50), \"pigeonholeDate\" VARCHAR(25), \"department\" VARCHAR(255), \"contentNo\" VARCHAR(20), \"relevanceNo\" VARCHAR(20), \"responsibleby\" VARCHAR(100), \"isRemind\" int4 ); COMMENT ON COLUMN tableName.\"arcInfoId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"expand\" IS '扩展字段'; COMMENT ON COLUMN tableName.\"parentId\" IS '父id'; COMMENT ON COLUMN tableName.\"outSideId\" IS '外部来源id'; COMMENT ON COLUMN tableName.\"deleteTime\" IS '删除时间'; COMMENT ON COLUMN tableName.\"createBatch\" IS '创建批次'; COMMENT ON COLUMN tableName.\"adjustTime\" IS '调出时间'; COMMENT ON COLUMN tableName.\"viewFileCount\" IS '查看原文次数'; COMMENT ON COLUMN tableName.\"viewCount\" IS '查看条目次数'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"storeRoomId\" IS '库房id'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"originalCount\" IS '原文数量'; COMMENT ON COLUMN tableName.\"commentCount\" IS '评论数量'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"isUse\" IS '是否利用'; COMMENT ON COLUMN tableName.\"isStore\" IS '是否入库'; COMMENT ON COLUMN tableName.\"isRecycle\" IS '是否回收站'; COMMENT ON COLUMN tableName.\"isDestory\" IS '是否销毁'; COMMENT ON COLUMN tableName.\"isCompilation\" IS '是否编研'; COMMENT ON COLUMN tableName.\"status\" IS '状态'; COMMENT ON COLUMN tableName.\"unitId\" IS '单位id'; COMMENT ON COLUMN tableName.\"seq\" IS '顺序号'; COMMENT ON COLUMN tableName.\"storageLocationName\" IS '存放位置'; COMMENT ON COLUMN tableName.\"compilationName\" IS '编研素材类型名称'; COMMENT ON COLUMN tableName.\"childCount\" IS '子条目数'; COMMENT ON COLUMN tableName.\"refCount\" IS '关联数量'; COMMENT ON COLUMN tableName.\"handouverUnit\" IS '原移交单位'; COMMENT ON COLUMN tableName.\"fondsNo\" IS '二级全宗号'; COMMENT ON COLUMN tableName.\"numberNo\" IS '份数'; COMMENT ON COLUMN tableName.\"arcFlag\" IS '归档标识'; COMMENT ON COLUMN tableName.\"arcNo\" IS '档号'; COMMENT ON COLUMN tableName.\"filingYear\" IS '归档年度'; COMMENT ON COLUMN tableName.\"pageNo\" IS '页数'; COMMENT ON COLUMN tableName.\"retention\" IS '保管期限（保管期限Y永久，D30定期30年，D10定期10年）'; COMMENT ON COLUMN tableName.\"createdDate\" IS '文件形成时间'; COMMENT ON COLUMN tableName.\"handoverTime\" IS '移交时间'; COMMENT ON COLUMN tableName.\"arcCtgNo\" IS '分类号'; COMMENT ON COLUMN tableName.\"pieceNo\" IS '件号'; COMMENT ON COLUMN tableName.\"maintitle\" IS '题名'; COMMENT ON COLUMN tableName.\"securityClass\" IS '密级'; COMMENT ON COLUMN tableName.\"folderLocation\" IS '存放位置'; COMMENT ON COLUMN tableName.\"pigeonholeDate\" IS '归档日期'; COMMENT ON COLUMN tableName.\"department\" IS '部门名称'; COMMENT ON COLUMN tableName.\"contentNo\" IS '目录号'; COMMENT ON COLUMN tableName.\"relevanceNo\" IS '批量关联号'; COMMENT ON COLUMN tableName.\"responsibleby\" IS '责任者'; COMMENT ON COLUMN tableName.\"isRemind\" IS '设置提醒 1是 0否'; COMMENT ON TABLE tableName IS '档案信息表';";
                    String origina = "CREATE TABLE tableName ( \"arcOriginalId\" int8 NOT NULL, \"tenantId\" int8, \"revision\" int4, \"createBy\" VARCHAR(32), \"createTime\" timestamp(6), \"updateBy\" VARCHAR(32), \"updateTime\" timestamp(6), \"deleted\" int4, \"arcInfoId\" int8, \"categoryId\" int8, \"qzId\" int8, \"fileName\" VARCHAR(255), \"fileNote\" VARCHAR(255), \"filePixel\" VARCHAR(255), \"fileDpi\" VARCHAR(255), \"fileSize\" VARCHAR(32), \"fileType\" VARCHAR(32), \"filePath\" VARCHAR(255), \"md5\" VARCHAR(100), \"indexStatus\" int4, \"seq\" int4, \"fileContenttype\" VARCHAR(200), \"localPath\" VARCHAR(255), \"ossPath\" VARCHAR(255) ); COMMENT ON COLUMN tableName.\"arcOriginalId\" IS '业务主键'; COMMENT ON COLUMN tableName.\"tenantId\" IS '租户号'; COMMENT ON COLUMN tableName.\"revision\" IS '乐观锁'; COMMENT ON COLUMN tableName.\"createBy\" IS '创建人'; COMMENT ON COLUMN tableName.\"createTime\" IS '创建时间'; COMMENT ON COLUMN tableName.\"updateBy\" IS '更新人'; COMMENT ON COLUMN tableName.\"updateTime\" IS '更新时间'; COMMENT ON COLUMN tableName.\"deleted\" IS '删除标识'; COMMENT ON COLUMN tableName.\"arcInfoId\" IS '档案业务id'; COMMENT ON COLUMN tableName.\"categoryId\" IS '门类id'; COMMENT ON COLUMN tableName.\"qzId\" IS '全宗id'; COMMENT ON COLUMN tableName.\"fileName\" IS '原文名称'; COMMENT ON COLUMN tableName.\"fileNote\" IS '原文注释'; COMMENT ON COLUMN tableName.\"filePixel\" IS '像素'; COMMENT ON COLUMN tableName.\"fileDpi\" IS '分辨率'; COMMENT ON COLUMN tableName.\"fileSize\" IS '原文大小'; COMMENT ON COLUMN tableName.\"fileType\" IS '原文类型'; COMMENT ON COLUMN tableName.\"filePath\" IS '访问路径'; COMMENT ON COLUMN tableName.\"md5\" IS 'MD5'; COMMENT ON COLUMN tableName.\"indexStatus\" IS '索引状态'; COMMENT ON COLUMN tableName.\"seq\" IS '原文序号'; COMMENT ON COLUMN tableName.\"fileContenttype\" IS '原文内容类型'; COMMENT ON COLUMN tableName.\"localPath\" IS '本地路径'; COMMENT ON COLUMN tableName.\"ossPath\" IS 'oss路径'; COMMENT ON TABLE tableName IS '档案原文表';";
                    StringBuilder sb = new StringBuilder();
                    sb.append(info.replace("tableName", ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix));
                    sb.append("\n");
                    sb.append(origina.replace("tableName", ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix));
                    FileUtil.writeUtf8String(sb.toString(), filePath);
                    //ArcUtils.execPGSql(host, port, password, filePath);
                    this.baseMapper.createArcInfoTableHg(ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix);
                    this.baseMapper.createArcOriginaTableHg(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix);


                }
            } else {//mysql数据源

                String filePath = uploadFolder + "archive" + IdWorker.getIdStr() + ".sql";
                String tmp = dataSourceUrl.substring(dataSourceUrl.indexOf("//") + 2);
                String[] split = tmp.substring(0, tmp.indexOf("/")).split(":");

                String host = split[0], port = split[1];
                if (ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR > 0) {
                    for (int i = 0; i < ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR; i++) {

                        String info = "create table tableName ( tenantId bigint(24) COMMENT '租户号' , revision INT(10) COMMENT '乐观锁' , createBy VARCHAR(32) COMMENT '创建人' , createTime DATETIME COMMENT '创建时间' , updateBy VARCHAR(32) COMMENT '更新人' , updateTime DATETIME COMMENT '更新时间' , deleted INT(1) DEFAULT 0 COMMENT '删除标识' , arcInfoId bigint(24) NOT NULL COMMENT '业务主键' , expand TEXT COMMENT '扩展字段' , parentId bigint(24) COMMENT '父id' , outSideId bigint(24) COMMENT '外部来源id' , deleteTime VARCHAR(25) COMMENT '删除时间' , createBatch VARCHAR(50) COMMENT '创建批次' , adjustTime VARCHAR(25) COMMENT '调出时间' , viewFileCount INT(10) COMMENT '查看原文次数' , viewCount INT(10) COMMENT '查看条目次数' , qzId bigint(24) COMMENT '全宗id' , storeRoomId bigint(24) COMMENT '库房id' , indexStatus INT(2) COMMENT '索引状态' , originalCount INT(10) COMMENT '原文数量' ,commentCount INT(10)    COMMENT '批量数量' , categoryId bigint(24) COMMENT '门类id' , isUse INT(1) COMMENT '是否利用' , isStore INT(1) COMMENT '是否入库' , isRecycle INT(1) COMMENT '是否回收站' , isDestory INT(1) COMMENT '是否销毁' , isCompilation INT(1) COMMENT '是否编研' , status INT(2) COMMENT '状态' , unitId bigint(24) COMMENT '单位id' , storageLocationName varchar(255) COMMENT '存放位置', compilationName varchar(255) COMMENT '编研素材类型名称', seq VARCHAR(10) COMMENT '顺序号' , childCount INT(10) COMMENT '子条目数' , refCount INT(10) COMMENT '关联数量', handouverUnit VARCHAR(255) COMMENT '原移交单位' , fondsNo VARCHAR(100) COMMENT '二级全宗号' , numberNo INT(10) COMMENT '份数' , arcFlag VARCHAR(60) COMMENT '归档标识' , arcNo VARCHAR(255) COMMENT '档号' , filingYear VARCHAR(10) COMMENT '归档年度' , pageNo INT(10) COMMENT '页数' , retention VARCHAR(10) COMMENT '保管期限（保管期限Y永久，D30定期30年，D10定期10年）' , createdDate VARCHAR(25) COMMENT '文件形成时间' , handoverTime VARCHAR(25) COMMENT '移交时间' , arcCtgNo VARCHAR(50) COMMENT '分类号' , pieceNo VARCHAR(20) COMMENT '件号' , maintitle VARCHAR(255) COMMENT '题名' , securityClass VARCHAR(20) COMMENT '密级' , folderLocation VARCHAR(50) COMMENT '存放位置' , pigeonholeDate VARCHAR(25) COMMENT '归档日期' , department VARCHAR(255) COMMENT '部门名称' , contentNo VARCHAR(20) COMMENT '目录号' , relevanceNo VARCHAR(20) COMMENT '批量关联号' , responsibleby VARCHAR(1000) COMMENT '责任者' , isRemind int default 0 comment '设置提醒 1是 0否', PRIMARY KEY (arcInfoId) ) COMMENT = '档案信息表' ;";
                        String origina = "create table tableName( tenantId bigint(24) COMMENT '租户号' , revision INT(10) COMMENT '乐观锁' , createBy VARCHAR(32) COMMENT '创建人' , createTime DATETIME COMMENT '创建时间' , updateBy VARCHAR(32) COMMENT '更新人' , updateTime DATETIME COMMENT '更新时间' , deleted INT(1) DEFAULT 0 COMMENT '删除标识' , arcOriginalId bigint(24) NOT NULL COMMENT '业务主键' , arcInfoId bigInt(24) COMMENT '档案业务id' , categoryId bigInt(24) COMMENT '门类id' , qzId bigInt(24) COMMENT '全宗id' , fileName VARCHAR(255) COMMENT '原文名称', fileNote VARCHAR(255) COMMENT '原文注释', filePixel VARCHAR(255) COMMENT '像素', fileDpi VARCHAR(255) COMMENT '分辨率', fileSize VARCHAR(32) COMMENT '原文大小', fileType VARCHAR(32) COMMENT '原文类型', filePath VARCHAR(255) COMMENT '访问路径', md5 VARCHAR(100) COMMENT 'MD5', indexStatus INT(1) COMMENT '索引状态', seq INT(10) COMMENT '原文序号', fileContenttype VARCHAR(200) COMMENT '原文内容类型', localPath VARCHAR(255) COMMENT '本地路径', ossPath VARCHAR(255) COMMENT 'oss路径', PRIMARY KEY (arcOriginalId) ) COMMENT = '档案原文表' ;";

                        StringBuilder sb = new StringBuilder();
                        sb.append(info.replace("tableName", ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix + "_" + i));
                        sb.append("\n");
                        sb.append(origina.replace("tableName", ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix + "_" + i));
                        FileUtil.writeUtf8String(sb.toString(), filePath);
                        //ArcUtils.execSql(host, port, password, filePath);

                        if (FlymeUtils.isWindows()) {
                            ArcUtils.execSql(host, port, password, filePath);
                        } else {
                            this.baseMapper.createArcInfoTable(ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix + "_" + i);
                            this.baseMapper.createArcOriginaTable(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix + "_" + i);
                        }
                    }
                } else {
                    String info = "create table tableName ( tenantId bigint(24) COMMENT '租户号' , revision INT(10) COMMENT '乐观锁' , createBy VARCHAR(32) COMMENT '创建人' , createTime DATETIME COMMENT '创建时间' , updateBy VARCHAR(32) COMMENT '更新人' , updateTime DATETIME COMMENT '更新时间' , deleted INT(1) DEFAULT 0 COMMENT '删除标识' , arcInfoId bigint(24) NOT NULL COMMENT '业务主键' , expand TEXT COMMENT '扩展字段' , parentId bigint(24) COMMENT '父id' , outSideId bigint(24) COMMENT '外部来源id' , deleteTime VARCHAR(25) COMMENT '删除时间' , createBatch VARCHAR(50) COMMENT '创建批次' , adjustTime VARCHAR(25) COMMENT '调出时间' , viewFileCount INT(10) COMMENT '查看原文次数' , viewCount INT(10) COMMENT '查看条目次数' , qzId bigint(24) COMMENT '全宗id' , storeRoomId bigint(24) COMMENT '库房id' , indexStatus INT(2) COMMENT '索引状态' , originalCount INT(10) COMMENT '原文数量' ,commentCount INT(10)    COMMENT '批量数量' , categoryId bigint(24) COMMENT '门类id' , isUse INT(1) COMMENT '是否利用' , isStore INT(1) COMMENT '是否入库' , isRecycle INT(1) COMMENT '是否回收站' , isDestory INT(1) COMMENT '是否销毁' , isCompilation INT(1) COMMENT '是否编研' , status INT(2) COMMENT '状态' , unitId bigint(24) COMMENT '单位id' , storageLocationName varchar(255) COMMENT '存放位置', compilationName varchar(255) COMMENT '编研素材类型名称', seq VARCHAR(10) COMMENT '顺序号' , childCount INT(10) COMMENT '子条目数' , refCount INT(10) COMMENT '关联数量', handouverUnit VARCHAR(255) COMMENT '原移交单位' , fondsNo VARCHAR(100) COMMENT '二级全宗号' , numberNo INT(10) COMMENT '份数' , arcFlag VARCHAR(60) COMMENT '归档标识' , arcNo VARCHAR(255) COMMENT '档号' , filingYear VARCHAR(10) COMMENT '归档年度' , pageNo INT(10) COMMENT '页数' , retention VARCHAR(10) COMMENT '保管期限（保管期限Y永久，D30定期30年，D10定期10年）' , createdDate VARCHAR(25) COMMENT '文件形成时间' , handoverTime VARCHAR(25) COMMENT '移交时间' , arcCtgNo VARCHAR(50) COMMENT '分类号' , pieceNo VARCHAR(20) COMMENT '件号' , maintitle VARCHAR(255) COMMENT '题名' , securityClass VARCHAR(20) COMMENT '密级' , folderLocation VARCHAR(50) COMMENT '存放位置' , pigeonholeDate VARCHAR(25) COMMENT '归档日期' , department VARCHAR(255) COMMENT '部门名称' , contentNo VARCHAR(20) COMMENT '目录号' , relevanceNo VARCHAR(20) COMMENT '批量关联号' , responsibleby VARCHAR(1000) COMMENT '责任者' , isRemind int default 0 comment '设置提醒 1是 0否', PRIMARY KEY (arcInfoId) ) COMMENT = '档案信息表' ;";
                    String origina = "create table tableName( tenantId bigint(24) COMMENT '租户号' , revision INT(10) COMMENT '乐观锁' , createBy VARCHAR(32) COMMENT '创建人' , createTime DATETIME COMMENT '创建时间' , updateBy VARCHAR(32) COMMENT '更新人' , updateTime DATETIME COMMENT '更新时间' , deleted INT(1) DEFAULT 0 COMMENT '删除标识' , arcOriginalId bigint(24) NOT NULL COMMENT '业务主键' , arcInfoId bigInt(24) COMMENT '档案业务id' , categoryId bigInt(24) COMMENT '门类id' , qzId bigInt(24) COMMENT '全宗id' , fileName VARCHAR(255) COMMENT '原文名称', fileNote VARCHAR(255) COMMENT '原文注释', filePixel VARCHAR(255) COMMENT '像素', fileDpi VARCHAR(255) COMMENT '分辨率', fileSize VARCHAR(32) COMMENT '原文大小', fileType VARCHAR(32) COMMENT '原文类型', filePath VARCHAR(255) COMMENT '访问路径', md5 VARCHAR(100) COMMENT 'MD5', indexStatus INT(1) COMMENT '索引状态', seq INT(10) COMMENT '原文序号', fileContenttype VARCHAR(200) COMMENT '原文内容类型', localPath VARCHAR(255) COMMENT '本地路径', ossPath VARCHAR(255) COMMENT 'oss路径', PRIMARY KEY (arcOriginalId) ) COMMENT = '档案原文表' ;";

                    StringBuilder sb = new StringBuilder();
                    sb.append(info.replace("tableName", ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix));
                    sb.append("\n");
                    sb.append(origina.replace("tableName", ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix));
                    FileUtil.writeUtf8String(sb.toString(), filePath);
                    //ArcUtils.execSql(host, port, password, filePath);

                    if (FlymeUtils.isWindows()) {
                        ArcUtils.execSql(host, port, password, filePath);
                    } else {
                        this.baseMapper.createArcOriginaTable(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + tableNameSuffix);
                        this.baseMapper.createArcInfoTable(ArchiveConstants.ARC_INFO_TABLE_PREFIX + tableNameSuffix);
                    }
                }
            }
        } catch (Exception e) {
            log.error("创建门类档案表异常", e);
            ApiAssert.failure("创建门类档案表异常，请尝试重新添加");
        }
    }

    @Override
    public void rollBackGenCategoryTable(String tableNameSuffix) {
        try {
            //暂时不处理表删除，防止由于异常造成有数据的表删除
//            if(ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR>0){
//                for(int i=0;i<ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR;i++){
//                    this.baseMapper.createArcInfoTable(ArchiveConstants.ARC_INFO_TABLE_PREFIX+tableNameSuffix+"_"+i);
//                    this.baseMapper.createArcOriginaTable(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX+tableNameSuffix+"_"+i);
//                }
//            }else{
//                this.baseMapper.createArcInfoTable(ArchiveConstants.ARC_INFO_TABLE_PREFIX+tableNameSuffix);
//                this.baseMapper.createArcOriginaTable(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX+tableNameSuffix);
//            }
        } catch (Exception e) {
            log.error("回滚档案表创建异常表名" + tableNameSuffix, e);
        }
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ArcCategory> cq, ArcCategory category, EntityMap requestMap) {
        cq.orderByDesc("category.createTime");
        return ResultBody.ok();
    }

    private void delRedisTableName(String tableName) {
        String tableSuffixNums = redisUtils.getString(ArchiveConstants.REDIS_TABLE_SUFFIX_KEY);
        if (FlymeUtils.isNotEmpty(tableSuffixNums) && tableSuffixNums.contains(tableName)) {
            String[] arr = tableSuffixNums.replace(tableName, "").split(",");
            if (arr.length > 0) {
                String newtableSuffixNums = Arrays.stream(arr).filter(item -> {
                    return item.trim().length() > 0;
                }).collect(Collectors.joining(","));
                if (newtableSuffixNums.trim().length() > 0) {
                    redisUtils.set(ArchiveConstants.REDIS_TABLE_SUFFIX_KEY, newtableSuffixNums, 600L);
                }
            }
        }
    }

    @Override
    public ResultBody getTableName(Map var1) {
        int offset = 0;
        //防止同时操作    tableName一致  设置偏移量
        String tableSuffixNums = redisUtils.getString(ArchiveConstants.REDIS_TABLE_SUFFIX_KEY);
        if (FlymeUtils.isNotEmpty(tableSuffixNums)) {
            offset = tableSuffixNums.split(",").length;
        }
        CriteriaQuery<ArcCategorySuffix> suffixQuery = new CriteriaQuery<ArcCategorySuffix>(ArcCategorySuffix.class);
        suffixQuery.orderByDesc("suffixNum");
        suffixQuery.limit(1);
        ArcCategorySuffix suffix = arcCategorySuffixService.getBaseMapper().selectOne(suffixQuery);
        Map<String, String> data = new HashMap();
        if (suffix == null) {
            data.put("tableName", ArcUtils.numberFormatStr(ArchiveConstants.ARC_TABLE_PREFIX_LENGTH, (int) Math.pow(10, (ArchiveConstants.ARC_TABLE_PREFIX_LENGTH - 1)) + offset));
        } else {
            data.put("tableName", ArcUtils.numberFormatStr(ArchiveConstants.ARC_TABLE_PREFIX_LENGTH, suffix.getSuffixNum() + 1 + offset));
        }
        if (FlymeUtils.isEmpty(tableSuffixNums)) {
            redisUtils.set(ArchiveConstants.REDIS_TABLE_SUFFIX_KEY, data.get("tableName"), 600L);
        } else {
            redisUtils.set(ArchiveConstants.REDIS_TABLE_SUFFIX_KEY, tableSuffixNums + "," + data.get("tableName"), 600L);
        }
        return ResultBody.ok(data);
    }

    @Override
    public ResultBody upOrDown(Map var1) {
        ApiAssert.isNotEmpty("门类id不能为空", var1.get("categoryId"));
        ApiAssert.isNotEmpty("移动类型不能为空", var1.get("type"));
        //排序为从小到大排   type为1为上移  2为下移
        Long categoryId = NumberUtil.parseLong(var1.get("categoryId") + "");
        Integer type = NumberUtil.parseInt(var1.get("type") + "");
        if (type != 1 && type != 2) {
            ApiAssert.failure("移动类型只能为上移或下移");
        }
        ArcCategory cate = this.getById(categoryId);
        CriteriaQuery<ArcCategory> query = new CriteriaQuery<ArcCategory>(ArcCategory.class);
        query.lambda().eq(ArcCategory::getParentId, cate.getParentId());//查询同级别的
        query.orderByAsc("seq");//基于seq从大到小排序
        List<ArcCategory> list = this.list(query);
        int sourceIndex = -1;
        int targetIndex = -1;
        for (int i = 0; i < list.size(); i++) {
            ArcCategory obj = list.get(i);
            if (obj.getCategoryId().equals(categoryId)) {
                if (type == 1) {//上移
                    if (i == 0) {
                        return ResultBody.failed("无法上移");
                    } else {
                        sourceIndex = i;
                        targetIndex = i - 1;
                    }
                } else if (type == 2) {//下移
                    if (i == list.size() - 1) {
                        return ResultBody.failed("无法下移");
                    } else {
                        sourceIndex = i;
                        targetIndex = i + 1;
                    }
                }
            }
        }
        if (sourceIndex < 0 || targetIndex < 0) {
            return ResultBody.failed("移动错误");
        }
        Long targetId = list.get(sourceIndex).getCategoryId();
        list.get(sourceIndex).setCategoryId(list.get(targetIndex).getCategoryId());
        list.get(targetIndex).setCategoryId(targetId);
        List<ArcCategory> updateObj = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            ArcCategory obj = new ArcCategory();
            obj.setCategoryId(list.get(i).getCategoryId());
            obj.setSeq(i);
            updateObj.add(obj);
        }
        this.saveOrUpdateBatch(updateObj);
        return ResultBody.ok();
    }

    @Override
    public void addArcCategorySuffix(String tableName, Long categoryId) {
        Integer suffixNum = null;
        try {
            suffixNum = new Integer(tableName);
        } catch (Exception e) {
            log.error("门类数据库表名转换错误", e);
            ApiAssert.failure("门类数据库表名转换错误");
        }
        ArcCategorySuffix suffix = new ArcCategorySuffix();
        suffix.setSuffix(tableName);
        suffix.setSuffixNum(suffixNum);
        suffix.setCategoryId(categoryId);
        suffix.setSideCar(ArchiveConstants.ARC_TABLE_DEFAULT_SIDECAR);
        suffix.setStatus(ArchiveEnumInteger.IS_TRUE.getCode());
        arcCategorySuffixService.save(suffix);
    }

    @Override
    public ResultBody beforeEdit(CriteriaUpdate<ArcCategory> cu, ArcCategory t, EntityMap extra) {
        ApiAssert.isNotEmpty("门类id不能为空", t.getCategoryId());
        OpenUser user = OpenHelper.getUser();
        ArcCategory c = this.getById(t.getCategoryId());
        if (ArchiveConstants.ROOT_PARENT_ID.equals(c.getParentId())) {
            if (!ArchiveEnumInteger.IS_ADMIN.getCode().equals(user.getSuperAdmin())) {
                return ResultBody.failed("只有系统管理员才能修改根节点");
            }
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody beforeDelete(CriteriaDelete<ArcCategory> cd) {
        ApiAssert.isNotEmpty("门类id不能为空", cd.getIdValue());
        ArcCategory c = this.getById(cd.getIdValue());
        if (ArchiveConstants.ROOT_PARENT_ID.equals(c.getParentId())) {
            return ResultBody.failed("门类根节点不能删除");
        }
        if (!CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(c.getType())) {
            //节点对应表中有数据无法删除
            //TODO 查询动态表是否有数据，有数据则不能删除
            //1 校验表中是否有档案
            LambdaQueryWrapper<ArcInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(ArcInfo::getCategoryId, cd.getIdValue());
            Long count = this.arcInfoService.count(lambdaQueryWrapper);
            if (FlymeUtils.isNotEmpty(count) && count > 0) {
                ApiAssert.failure("门类已添加档案，无法删除");
            }
        }

        //2 校验上级是否有档案  如果有则不能删除
        checkCanDeleteByParent(c);

        if (!CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(c.getType())) {

            //删除档案表、原文表
            this.baseMapper.deleteArcInfoTable(ArchiveConstants.ARC_INFO_TABLE_PREFIX + c.getTableName());
            this.baseMapper.deleteOriginalTable(ArchiveConstants.ARC_ORIGINAL_TABLE_PREFIX + c.getTableName());
            //级联删除档案表、档案原文表、arc_field中对应门类的字段
            arcFieldService.delArcField(c.getCategoryId());
            arcCategorySuffixService.delCategory(c.getCategoryId());
            arcDestoryService.delCategory(c.getCategoryId());
        }

        return ResultBody.ok();
    }


    private void checkCanDeleteByParent(ArcCategory parentCategory) {
        if (parentCategory != null
                && !ArchiveConstants.ROOT_PARENT_ID.equals(parentCategory.getCategoryId())
                && !CategoryTypeEnum.CATEGORY_TYPE_0.getCode().equals(parentCategory.getType())) {
            LambdaQueryWrapper<ArcInfo> parentLambdaQueryWrapper = new LambdaQueryWrapper<>();
            parentLambdaQueryWrapper.eq(ArcInfo::getCategoryId, parentCategory.getCategoryId());
            Long parentCount = this.arcInfoService.count(parentLambdaQueryWrapper);
            if (FlymeUtils.isNotEmpty(parentCount) && parentCount > 0) {
                // 如果上级有数据 校验当前门类级别是否有兄弟
                LambdaQueryWrapper<ArcCategory> brotherCategoryQueryWrapper = new LambdaQueryWrapper<ArcCategory>();
                brotherCategoryQueryWrapper.eq(ArcCategory::getParentId, parentCategory.getCategoryId());
                Long brotherCount = this.count(brotherCategoryQueryWrapper);
                if (brotherCount != null && brotherCount == 1) {
                    ApiAssert.failure("门类上级有数据，请先删除上级档案数据");
                }
            } else {
                ArcCategory parentParent = this.getById(parentCategory.getParentId());
                checkCanDeleteByParent(parentParent);
            }
        }
    }


    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<ArcCategory> cq, ArcCategory t, EntityMap requestMap) {
        ApiAssert.isNotEmpty("参数不能为空", t);
        ApiAssert.isNotEmpty("全宗id不能为空", t.getQzId());
        String listByRole = requestMap.get("listByRole");
        if (listByRole != null && listByRole.equals("listByRole")) {
            //过滤用户角色权限
            cq.inSql("category.categoryId", "select cu.categoryId from arc_category_user cu " +
                    "left join base_role_user ru on cu.roleId = ru.roleId where ru.userId = " + OpenHelper.getUserId());
        }
        //TODO 添加查询条件
        cq.eq("parentId");
        //批量关联模块获取门类（只获取）
        String queryType = requestMap.get("queryType");
        if (FlymeUtils.isNotEmpty(queryType)) {
            switch (queryType) {
                case "COMPILATION":
                    //编研素材 门类列表
                    JoinBean join = cq.createJoin(ArcCompilationRef.class);
                    join.setMainField("categoryId");
                    join.setJoinField("categoryId");
                    join.setJoinAlias("ref");
                    Long compilationId = requestMap.getLong("compilationId");
                    ApiAssert.isNotEmpty("编研素材id不能为空", compilationId);
                    cq.eq("ref.compilationId", compilationId);
                    cq.addSelect("category.cnName as cnName", "category.categoryId as categoryId");
                    List<String> groupByList = new ArrayList<String>();
                    groupByList.add("category.categoryId");
                    groupByList.add("category.cnName");
                    cq.groupBy(groupByList);
                    break;
                case "BATCH"://批量关联 只获取项目和案卷
                    //型0文件夹1项目2案卷3卷内4简化
                    cq.lambda().in(ArcCategory::getType, CategoryTypeEnum.CATEGORY_TYPE_1.getCode()
                            , CategoryTypeEnum.CATEGORY_TYPE_2.getCode());
                    //break;

                default:
                    cq.and(wrap -> {
                        wrap.lambda().eq(ArcCategory::getQzId, t.getQzId())
                                .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
                    });
                    break;
            }
        } else {
            cq.and(wrap -> {
                wrap.lambda().eq(ArcCategory::getQzId, t.getQzId())
                        .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
            });
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody getTreeByParentId(Map var1) {
        Object parentId = var1.get("parentId");
        Object qzId = var1.get("qzId");
        ApiAssert.isNotEmpty("全宗id不能为空", qzId);
        if (FlymeUtils.isEmpty(parentId)) {
            ApiAssert.failure("父id和父编码不能为空");
        }
        if (ArchiveConstants.ROOT_PARENT_ID.equals(Long.parseLong(parentId.toString()))) {
            return this.listEntityMap(var1);
        }
        ArcCategory obj = getById(Long.parseLong(parentId.toString()));
        if (FlymeUtils.isEmpty(obj)) {
            ApiAssert.failure("根据父id或者父编码无法查询到内容");
        }
        CriteriaQuery<ArcCategory> listQuery = new CriteriaQuery<ArcCategory>(ArcCategory.class);
        //过滤用户角色权限
        listQuery.inSql("categoryId", "select cu.categoryId from arc_category_user cu " +
                "left join base_role_user ru on cu.roleId = ru.roleId where ru.userId = " + OpenHelper.getUserId());


        //根据全宗id过滤   或   类型属于系统级别
        listQuery.and(wrap -> {
            wrap.lambda().eq(ArcCategory::getQzId, Long.parseLong(qzId.toString()))
                    .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
        });

        listQuery.likeRight("sysCode", obj.getSysCode());
        List<ArcCategory> list = list(listQuery);
        return ResultBody.ok(list);
    }

    //回收站下门类
    @Override
    public ResultBody recycleCategory(Map param) {
        Object qzId = param.get("qzId");
        ApiAssert.isNotEmpty("全宗Id不能为空", qzId);
        LambdaQueryWrapper<ArcCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(ArcCategory::getType, CategoryTypeEnum.CATEGORY_TYPE_0.getCode())
                .likeRight(ArcCategory::getSysCode, "A0" + param.get("parentId"));

        //过滤用户角色权限
        lambdaQueryWrapper.inSql(ArcCategory::getCategoryId, "select cu.categoryId from arc_category_user cu " +
                "left join base_role_user ru on cu.roleId = ru.roleId where ru.userId = " + OpenHelper.getUserId());


        //根据全宗id过滤   或   类型属于系统级别
        lambdaQueryWrapper.and(wrap -> {
            wrap.eq(ArcCategory::getQzId, Long.parseLong(qzId.toString()))
                    .or().eq(ArcCategory::getIsSystem, ArchiveEnumInteger.IS_SYSTEM.getCode());
        });


        List<ArcCategory> categories = this.list(lambdaQueryWrapper);
        Map<Long, ArcCategory> categoryMap = categories.stream()
                .collect(Collectors.toMap(ArcCategory::getCategoryId, ArcCategory -> ArcCategory));
        List<Future<Long>> futures = new ArrayList<>();
        Long userId = OpenHelper.getUserId();
        categories.forEach(item -> {
            final Map map = new HashMap();
            map.putAll(param);
            map.put("tempUserId_", userId);
            Future<Long> future = syncService.categoryHasRecycleArcQuery(item.getCategoryId(), null, map);
            futures.add(future);
        });
        List<ArcCategory> result = new ArrayList<>();
        futures.forEach(item -> {
            try {
                Long l = item.get();
                if (!l.equals(0L)) {
                    ArcCategory category = categoryMap.get(l);
                    if (FlymeUtils.isNotEmpty(category)) {
                        result.add(category);
                    }
                }

            } catch (Exception e) {
                log.error("获取门类异常", e);
                ApiAssert.failure("获取门类异常");
            }
        });
        return ResultBody.ok(result);
    }

    @Override
    public ResultBody collectCategory(Map param) {
        Object qzId = param.get("qzId");
        ApiAssert.isNotEmpty("全宗Id不能为空", qzId);
        List<Long> categoryIds = arcInfoCollectService.getCategoryIds(param, OpenHelper.getUserId());
        if (CollUtil.isEmpty(categoryIds)) {
            return ResultBody.ok(Collections.EMPTY_LIST);
        }
        LambdaQueryWrapper<ArcCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ArcCategory::getCategoryId, categoryIds)
                .likeRight(ArcCategory::getSysCode, "A0" + param.get("parentId"))
                .eq(ArcCategory::getQzId, Long.parseLong(qzId.toString()));

        List<ArcCategory> categories = this.list(lambdaQueryWrapper);
        Map<Long, ArcCategory> categoryMap = categories.stream()
                .collect(Collectors.toMap(ArcCategory::getCategoryId, ArcCategory -> ArcCategory));
        List<Future<Long>> futures = new ArrayList<>();
        Long userId = OpenHelper.getUserId();
        categories.forEach(item -> {
            final Map map = new HashMap();
            map.putAll(param);
            map.put("tempUserId_", userId);
            Future<Long> future = syncService.categoryHasCollectArcQuery(item.getCategoryId(), null, map);
            futures.add(future);
        });
        List<ArcCategory> result = new ArrayList<>();
        futures.forEach(item -> {
            try {
                Long l = item.get();
                if (!l.equals(0L)) {
                    ArcCategory category = categoryMap.get(l);
                    if (FlymeUtils.isNotEmpty(category)) {
                        result.add(category);
                    }
                }

            } catch (Exception e) {
                log.error("获取门类异常", e);
                ApiAssert.failure("获取门类异常");
            }
        });
        return ResultBody.ok(result);
    }


}
